package com.xlx.openLink.snmp.tk;

import net.percederberg.mibble.*;
import net.percederberg.mibble.snmp.SnmpObjectType;
import net.percederberg.mibble.type.ElementType;
import net.percederberg.mibble.type.SequenceType;
import net.percederberg.mibble.value.ObjectIdentifierValue;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import  static  com.xlx.openLink.snmp.tk.Constant.*;
/**
 * Created by heer on 2018/7/30.
 */
public class MibUtil {

    /**
     * 根据文件提取出mib
     * @param
     * @return
     * @throws MibLoaderException
     * @throws IOException
     */
    public static Mib loadMib(String path) throws MibLoaderException, IOException {
        File file = new File(path);
        MibLoader loader = new MibLoader();
        loader.addDir(file.getParentFile());
        Mib mib = loader.load(file);
        return mib;
    }

    /**
     * 根据oid获取mib symbol对象
     * @param oid
     * @return
     */
    public static MibValueSymbol getMibSymbolByOID(Mib mib,String oid){
        MibValueSymbol symbol = mib.getSymbolByOid(oid);
        if(symbol!=null){
            return symbol;
        }
        return null;
    }
    /**
     * 通过mib symbol的name获取className
     * @param symbol
     * @return
     */
    public static String getClassNameBySymbolName(MibValueSymbol symbol){
        return symbol.getName();
    }

    /**
     * 根据mibType得到java的type
     * @param type
     * @return
     */
    public static String getColTypeByMibType(MibType type){
        MibTypeSymbol symbol = type.getReferenceSymbol();
        String name;
        String result = "";
        if(symbol!=null) {
            name = symbol.getName();
            if (name.contains("Integer32")) {
                result = "Integer32";
            } else if (name.contains("Unsigned32")) {
                result = "Gauge32";
            } else if (name.contains("Gauge32")) {
                result = "Gauge32";
            } else if (name.contains("OID")) {
                result = "OID";
            } else if (name.contains("TimeTicks")) {
                result = "TimeTicks";
            } else if (name.contains("Counter32")) {
                result = "Counter32";
            } else if (name.contains("Opaque")) {
                result = "Opaque";
            } else if (name.contains("Counter64")) {
                result = "Counter64";
            } else if (name.contains("IpAddress")) {
                result = "IpAddress";
            } else {
                result = "OctetString";
            }
        }else {
            //element[i].type.reference为空，直接取element[i].type.name
            name = type.getName();
            if (name.contains("INTEGER")) {
                result = "Integer";
            } else if (name.contains("OCTET STRING")) {
                result = "OctetString";
            }
        }
        return result;
    }

    private static String getType(MibType type) {
        MibType var1 = type;
        if (var1.hasTag(0, 2)) {
            return "Integer";
        } else if (var1.hasTag(1, 1)) {
            return "Long";
        } else if (var1.hasTag(1, 2)) {
            return "Long";
        } else if (var1.hasTag(0, 4)) {
            return "String";
        } else if (var1.hasTag(0, 6)) {
            return "String";
        } else if (var1.hasTag(1, 0)) {
            return "String";
        } else if (var1.hasTag(1, 3)) {
            return "Long";
        } else if (var1.hasTag(1, 4)) {
            return "String";
        } else if (var1.hasTag(1, 6)) {
            return "Long";
        } else {
            System.err.print("未知的SNMP MIB数据类型: " + var1 + "，  将用String类型来映射（仅用于SNMP查询操作）");
            return "    String";
        }
    }

    /**
     * 根据mib symbol获取所有的行（属性）
     * @param symbol
     * @return
     */
    public static List<String> getColumns(MibValueSymbol symbol){
        SnmpObjectType objectType = (SnmpObjectType)symbol.getType();
        SequenceType sequenceType = (SequenceType) objectType.getSyntax();
        ElementType[] elementTypes = sequenceType.getAllElements();
        List<String> columns = new ArrayList();
        columns.add("tableIndexOID"+ Constant.REGEX+"String");
        for (int i=0;i<elementTypes.length;i++){
            String colName = elementTypes[i].getName();
            String colType = getType(elementTypes[i].getType());
            columns.add(colName+ Constant.REGEX+colType);
        }
        return columns;
    }

    /**
     * 获取声明属性和set，get方法的构造字符串
     * @param columns
     * @return
     */
    public static String getColumnsString(List<String> columns){
        StringBuilder sb = new StringBuilder();
        String[] temp;//temp[0]是属性名，temp[1]是类型名
        for (String colName:columns) {
            temp = colName.split(Constant.REGEX);
            sb.append("\tprivate "+temp[1]+" "+temp[0]+";\r\n");
        }
        for(String colName:columns){
            temp = colName.split(Constant.REGEX);
            sb.append("\tpublic "+temp[1]+ " get"+turnFirstUp(temp[0])
                    +"(){\r\n");
            sb.append("\t\treturn "+temp[0]+";\r\n");
            sb.append("\t}\r\n");
            sb.append("\tpublic void set"+turnFirstUp(temp[0])
                    + "("+temp[1]+" "+temp[0]+"){\r\n");
            sb.append("\t\tthis."+temp[0]+"="+temp[0]+";\r\n");
            sb.append("\t}\r\n");
        }
        return sb.toString();
    }

    /**
     * 将第一个字符转为大写
     * @param str
     * @return
     */
    public static String turnFirstUp(String str) {
        char[] ch = str.toCharArray();
        if(ch[0]>='a'&&ch[0]<='z'){
            ch[0]=(char)(ch[0]-32);
        }
        return new String(ch);
    }

    /**
     * 获取索引的list
     * @param symbol
     * @return
     */
    public static List<String> getIndex(MibValueSymbol symbol){
        ObjectIdentifierValue objectValue = (ObjectIdentifierValue)symbol.getValue();
        ObjectIdentifierValue[] values = objectValue.getAllChildren();
        String index;
        String name;
        List<String> temp = new ArrayList<>();
        String[] tempString;
        for (int i = 0; i < values.length; i++) {
            tempString = String.valueOf(values[i]).split("\\.");
            index = tempString[tempString.length-1];
            name = values[i].getName();
            temp.add(name+Constant.REGEX+index);
        }
        return temp;
    }

    /**
     * 获取索引的字符串
     * @param indexs
     * @return
     */
    public static String getIndexString(List<String> indexs){
        StringBuilder sb = new StringBuilder();
        String[] temp;//temp[0]是属性名，temp[1]是OID
        sb.append("\tpublic Map getIndexMap(){"+"\r\n");
        sb.append("\t   Map map = new LinkedHashMap();\r\n");
        String var0;

        for (String value:indexs){
            temp = value.split(REGEX);
            var0 = "\t   map.put("+"\""+temp[0]+"\""+","+temp[1]+");\r\n";
            //var0 = "\""+temp[0]+"=\"+"+"\""+temp[1]+"\""+"+"+"\""+"|"+"\""+"+";
            sb.append(var0);
        }
        sb.append("\t   return map;\r\n");
        sb.append("\t}\r\n");
        return sb.toString();
    }

    /**
     * 获取值的字符串
     * @param indexs
     * @return
     */
    public static String getValueString(List<String> indexs){
        StringBuilder sb = new StringBuilder();
        String[] temp;//temp[0]是属性名，temp[1]是OID
        sb.append("\tpublic Map getValues(){"+"\r\n");
        sb.append("\t   Map map = new LinkedHashMap();\r\n");

        String var0;
        for (String value:indexs){
            temp = value.split(REGEX);
            var0 = "\t   if(get"+turnFirstUp(temp[0])+"()!=null){\r\n";
            var0 += "\t         map.put("+"\""+temp[0]+"\""+",get"+turnFirstUp(temp[0])+"());\r\n";
            var0 += "\t     }\r\n";
            sb.append(var0);
        }
        sb.append("\t   return map;\r\n");
        sb.append("\t}\r\n");
        return sb.toString();
    }

    /**
     * 获取索引值的字符串
     * @param indexs
     * @return
     */
    public static String getIndexValueString(List<String> indexs){
        StringBuilder sb = new StringBuilder();
        String[] temp;//temp[0]是属性名，temp[1]是OID
        sb.append("\tpublic String getIndexValue(){"+"\r\n");
        String var0;
        var0 = "\t   if(getIndexCount()==1)\r\n";
        var0 += "\t      return get"+turnFirstUp(indexs.get(0).split(REGEX)[0])+"()"+".toString();\r\n";
        var0 += "\t   return getTableIndexOID();\r\n";
        var0 += "\t }\r\n";
        sb.append(var0);
        return sb.toString();
    }

    /**
     * 获取设置值的字符串
     * @param columns
     * @return
     */
    public static String getSetValueString(List<String> columns,String className){
        StringBuilder sb = new StringBuilder();
        className = turnFirstUp(className);
        String[] temp;//temp[0]是属性名，temp[1]是类型名
        sb.append("\tpublic "+className+" setValue(List list){"+"\r\n");
        sb.append("\t     "+className+" obj = new "+className+"();\r\n");
        String var0;
        String column;
        for(int i=1;i<columns.size();i++){
            column = columns.get(i);
            temp = column.split(REGEX);
            var0 = "\t     obj.set"+turnFirstUp(temp[0])+"(("+temp[1]+")list.get("+(i-1)+"));\r\n";
            sb.append(var0);
        }
        sb.append("\t     return obj;\r\n");

        sb.append("\t }\r\n");
        return sb.toString();
    }


    /**
     * 排除掉oid的第一个“.”
     * @param oid
     * @return
     */
    public static String getOID(String oid){
        if(oid.startsWith(".")){
            return oid.substring(1);
        }
        return oid;
    }

    /**
     * 重写父类的getMappingOID()方法
     * @return
     */
    public static String getOidString(String oid){
        StringBuilder sb = new StringBuilder();
        sb.append("\tpublic String getMappingOID(){"+"\r\n");
        sb.append("\t   return "+"\""+oid.toString()+"\";\r\n");
        sb.append("}\r\n");
        return sb.toString();
    }

    /**
     * 判断mib是单索引还是双索引
     * @return
     */
    public static String getIndexCount(MibValueSymbol symbol){
        StringBuilder sb = new StringBuilder();
        sb.append("\tpublic Integer getIndexCount(){"+"\r\n");
        SnmpObjectType objectType = (SnmpObjectType) symbol.getType();

        sb.append("\t   return "+""+objectType.getIndex().size()+";\r\n");
        sb.append("     }\r\n");
        return sb.toString();
    }

    /**
     * toString()方法
     * @return
     */
    public static String getToString(List<String> columns){
        StringBuilder sb = new StringBuilder();
        sb.append("\tpublic String toString(){"+"\r\n");
        sb.append("\t   return ");
        String[] temp;//temp[0]是属性名，temp[1]是类型名
        String var0;
        for(String column:columns){
            temp = column.split(REGEX);
            var0 = "\""+temp[0]+"=\"+"+temp[0]+"+"+"\""+"|"+"\""+"+";
            sb.append(var0);
        }
        sb = new StringBuilder(sb.substring(0,sb.length()-1));
        sb.append(";\r\n");
        sb.append("\t}\r\n");
        return sb.toString();
    }

    /**
     * 获取注释
     * @return
     */
    public static String getNotesString(){
        StringBuilder sb = new StringBuilder();
        sb.append(CODE_NOTES+"\r\n");
        return sb.toString();
    }

    /**
     * 将字符串写进java文件
     * @param savePath
     * @param className
     * @param sb
     */
    public static void write(String savePath,String className,String sb){
        try{
            String path=savePath+turnFirstUp(className)+JAVA_FILE_SUFFIX;
            File file=new File(path);
            if(file.exists()){
                file.delete();
                file.createNewFile();
            }
            FileOutputStream out=new FileOutputStream(file,true);
            out.write(sb.getBytes("utf-8"));
            out.close();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }
}
